package com.itheima.stock.service.impl;

import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.itheima.stock.common.domain.StockInfoConfig;
import com.itheima.stock.mapper.StockBlockRtInfoMapper;
import com.itheima.stock.mapper.StockBusinessMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.mapper.StockRtInfoMapper;
import com.itheima.stock.pojo.StockBusiness;
import com.itheima.stock.service.StockService;
import com.itheima.stock.utils.DateTimeUtil;
import com.itheima.stock.vo.resp.PageResult;
import com.itheima.stock.vo.resp.R;
import com.itheima.stock.vo.resp.StockExcelDomain;
import org.ehcache.core.util.CollectionUtil;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

@Service
public class StockServiceImpl implements StockService {
    @Autowired
    private StockBusinessMapper stockBusinessMapper;

    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    @Autowired
    private StockInfoConfig stockInfoConfig;

    //注入mapper接口
    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;

    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;


    @Override
    public List<StockBusiness> getAllStockBusiness() {

        return stockBusinessMapper.getAll();
    }

    @Override
    public R<List<Map>> getInnerStockMarket() {
        //获取最近股票有效交易日，精确到分钟
        String lastAvDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        //设置成有效数据（数据库测试数据可能不存在）
        lastAvDate = "20211228095300";
        List<Map> infos = this.stockMarketIndexInfoMapper.getInnerStockMarket(stockInfoConfig.getInner(), lastAvDate);
        if (CollectionUtils.isEmpty(infos)) {
            return R.error("暂无数据");
        }
        return R.ok(infos);
    }

    /**
     * 获取国内最新大盘指数
     *
     * @return
     */
    @Override
    public R<List<Map>> getSectorAllLimit() {
        List<Map> maps = this.stockBlockRtInfoMapper.getSectorAllLimit();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂时没有数据");
        }
        return R.ok(maps);
    }

    /**
     * 涨幅榜
     * 沪深两市个股涨幅分时行情数据查询，以时间顺序查询前10条数据
     *
     * @return
     */


    @Override
    public R<List<Map>> getStockIncrease() {
        List<Map> maps = this.stockRtInfoMapper.getStockIncrease();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂时没有数据！");
        }
        return R.ok(maps);
    }


    /**
     * 沪深两市个股行情列表查询 ,以时间顺序和涨幅排序分页查询
     *
     * @param page     当前页
     * @param pageSize 每页大小
     * @return
     */
    @Override
    public R<PageResult> getStockAll(Integer page, Integer pageSize) {
        //设置分页参数
        PageHelper.startPage(page, pageSize);
        //查询
        List<Map> maps = this.stockRtInfoMapper.getStockAll();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂无数据");
        }
        PageInfo<Map> pageInfo = new PageInfo<>(maps);
        PageResult<Map> pageResult = new PageResult<>(pageInfo);
        return R.ok(pageResult);
    }

    @Override
    public R<Map> getStockUpDownLimitCount() {
        //获取涨停统计数
        List<Map> upLimit = this.stockRtInfoMapper.getUpDownLimitCount(1);
        String curDate = DateTime.now().toString(DateTimeFormat.forPattern("yyyyMMddHHmm"));
        if (CollectionUtils.isEmpty(upLimit)) {
            //设置默认值
            HashMap<String, Object> map = new HashMap<>();
            map.put("time", curDate);
            map.put("count", 0);
            upLimit.add(map);
        }
        //获取跌停统计数
        List<Map> downLimit = this.stockRtInfoMapper.getUpDownLimitCount(0);
        if (CollectionUtils.isEmpty(upLimit)) {
            //设置默认值
            HashMap<String, Object> map = new HashMap<>();
            map.put("time", curDate);
            map.put("count", 0);
            downLimit.add(map);
        }
        //组装数据
        HashMap<String, List<Map>> map = new HashMap<>();
        map.put("upList", upLimit);
        map.put("downList", downLimit);
        return R.ok(map);
    }

    /**
     * 涨幅榜数据分页导出到excel
     *
     * @param response 用于响应excel文件
     * @param page     当前页
     * @param pageSize 每页大小
     */
    @Override
    public void exportStockExcel(HttpServletResponse response, Integer page, Integer pageSize) {
        try {
            //设置响应数据格式
            response.setContentType("application/vnd.ms-excel");
            //设置编码
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("stockRt", "UTF-8");
            //设置默认文件名称
            response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xlsx");
            //获取导出的分页数据
            PageHelper.startPage(page, pageSize);
            List<Map> maps = this.stockRtInfoMapper.getStockAll();
            List<StockExcelDomain> domains = new ArrayList<>();
            //转化成StockExcelDomain对象
            Gson gson = new Gson();
            maps.forEach(row -> {
                StockExcelDomain domain = gson.fromJson(gson.toJsonTree(row), StockExcelDomain.class);
                domains.add(domain);
            });
            EasyExcel.write(response.getOutputStream(), StockExcelDomain.class)
                    .sheet("stockRt").doWrite(domains);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 成交量对比
     * 沪深两市个股涨跌行情数据查询，查询T日分时成交量与T-1日分时成交量对比数据
     * 简言之，统计两市成交量在每分钟的之和的统计；
     *
     * @return
     */
    @Override
    public R<Map> getStockTravolCompare() {
        //获取最近时间的一个交易日
        DateTime target = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //转string
        String curTStr = DateTimeUtil.parseToString4Stock(target);
        //T-1的日期数据
        String preTStr = DateTimeUtil.parseToString4Stock(DateTimeUtil.getPreviousTradingDay(target));

        //获取T日成交量数据
        List<Map> nowDatas = this.stockMarketIndexInfoMapper.getStockTravol(curTStr);
        if (CollectionUtils.isEmpty(nowDatas)) {
            nowDatas = Collections.emptyList();
        }
        //获取T-1数据
        List<Map> preDatas = this.stockMarketIndexInfoMapper.getStockTravol(preTStr);
        if (CollectionUtils.isEmpty(preDatas)) {
            preDatas = Collections.emptyList();
        }
        //组装数据
        HashMap<String, List> map = new HashMap<>();
        map.put("volList", nowDatas);
        map.put("yesVolList", preDatas);
        return R.ok(map);
    }

    /**
     * 查询当前时间下股票的涨跌幅度区间统计功能
     * 如果当前日期不在有效时间内，则以最近的一个股票交易时间作为查询点
     *
     * @return
     */
    @Override
    public R<Map> getStockUpDownScope() {
        //获取最近的有效股票交易时间，精确到分钟
        DateTime target = DateTimeUtil.getLastDate4Stock(DateTime.now());
        String last = DateTimeUtil.getLastDateString4Stock(target);
        last = "20220102145800";
//查询最近价格
        List<Map> maps = this.stockRtInfoMapper.getStockUpDownScope(last);
        //设置
        if (CollectionUtils.isEmpty(maps)) {
            maps = Collections.emptyList();
        }
        List<String> upDownRange = stockInfoConfig.getUpDownRange();
        List<Map> lists = new ArrayList<>();
        for (String range : upDownRange) {
            Map orderMap = null;
            for (Map map : maps) {
                if (range.equals(map.get("title"))) {
                    orderMap = map;
                    break;
                }
            }
            if (orderMap == null) {
                orderMap = new HashMap<>();
                orderMap.put("title",range);
                orderMap.put("count",0);
            }
            lists.add(orderMap);
        }
        HashMap<String, Object> info = new HashMap<>();
        info.put("time", target.toString("yyyy-MM-dd HH:mm:ss"));
        info.put("infos", lists);
        return R.ok(info);
    }
    /**
     * 个股分时行情
     * 查询单个个股的分时行情数据，查询时间周期是T日开盘到当前时间
     * @param stockCode 个股编码
     * @return
     */
    @Override
    public R<List<Map>> getStockScreenMinuteSharing(String stockCode) {
        //获取最近有效交易时间
        String tDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        //虚拟数据
        tDate = "20220102145800";
        //查询

        List<Map> infos= this.stockRtInfoMapper.getStockScreenMinuteSharing(stockCode,tDate);
        if (CollectionUtils.isEmpty(infos)) {
            return R.error("暂无数据");
        }
        return R.ok(infos);
    }

    /**
     * 单个个股日K 数据查询 ，可以根据时间区间查询数日的K线数据
     * @param stockCode 股票编码
     */
    @Override
    public R<List<Map>> getDayKLinData(String stockCode) {
        DateTime hisDate = DateTime.now().minusDays(20);
        //获取日期字符串
        String hisDateStr=hisDate.toString(DateTimeFormat.forPattern("yyyyMMdd"));
        //虚拟数据
        hisDateStr = "20220103";
        List<Map> infos= this.stockRtInfoMapper.getDayKLinData(stockCode,hisDateStr);
        if (CollectionUtils.isEmpty(infos)) {
            return R.error("暂无数据");
        }
        return R.ok(infos);
    }
    /**
     * 外盘指数
     * 外盘指数行情数据查询，根据时间和大盘点数降序排序取前4
     * @return
     */
    @Override
    public R<List<Map>> getOnlyStockMarketIndex() {
        List<Map> maps=this.stockRtInfoMapper.getOnlyStockMarketIndex();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂时没有数据！");
        }
        return R.ok(maps);

    }


}
